
angular.module('zixys.gradient',[])
    
    .directive('zixysPresets',["gradientPresets", 'gradList', 'Colors','newGradient', function(gradientPresets, gradList, Colors, newGradient) {
        return {
            restrict: 'C',
            replace: true,
            template : '<div >' +
                            '<input ng-disabled="disabled" id="zixys-presets" type="button" value="Presets" />' +
                            '<div id="zixys-preset-window">' +
                                '<div class="zixys-preset-sample" ng-repeat="preset in presets.textDefaults" ng-click="parse($index)" style="{{sample(preset)}}"></div>'+
                            '</div>' +
                        '</div>',
            scope: {
                output:"=zixysPresets",
                disabled:"=ngDisabled"
            },
            link : function($scope, element, attrs) {

                $scope.presets = gradientPresets;

                var win = element.find('#zixys-preset-window'),
                    button = element.find('#zixys-presets');

                function open() {
                    win.show();
                };

                function close() {
                    win.hide();
                };

                $scope.stringify = Colors.stringifyColor;

                $scope.sample = function(str) {
                    var out =
                        'background-image: linear-gradient(-45deg, '+str+');'+
                        'background-image: -o-linear-gradient(-45deg, '+str+') ;'+
                        'background-image: -moz-linear-gradient(-45deg, '+str+') ;'+
                        'background-image: -webkit-linear-gradient(-45deg, '+str+') ;'+
                        'background-image: -ms-linear-gradient(-45deg, '+str+') ;';
                    return out;
                }

                function addPreset(background, id) {
                    $('<div class="zixys-preset-sample"></div>')
                        .attr('style',background)
                        .click(function(){
                            if ( !gradientPresets.deployed[id] ) {
                                gradientPresets.deployed[id] = gradientPresets.deploySet(gradientPresets.defaults[id]);
                            }
                            $scope.$emit('gradient.presetLoaded',gradientPresets.deployed[id]);
                        })
                        .appendTo(win);
                }

                $scope.parse = function(index) {

                    var tmpPreset = gradientPresets.textDefaults[index].split(','),
                        markers = [];
                    for (var j=0; j<tmpPreset.length; j++) {
                        markers.push(Colors.parseColorStop(tmpPreset[j]));
                    }
                    var grad = newGradient('gr-pr-'+index);

                    grad.markers = markers;
                    gradList.list.length = 0;
                    gradList.list.push(grad);
                    gradList.selected = grad;
                }

                button.click(function(e){
                   open();
                   e.stopPropagation();
                });
                
                $(document).click(function(){
                   close(); 
                });
            }
        }
    }])

    .service('gradList',[function(){
        this.list = [];
        this.selected = {};
        this.marker = {};
        this.zxNode = null;

        this.$_deploy = function(){
            if(!this.zxNode) return;
            this.zxNode.setData('gradient',this.list);
        }

        this.$_reset = function(){
            this.list = [];
            this.selected = {};
            this.marker = {};
        }
    }])

    .factory('newMarker',['Colors',function(Colors){
        return function (customs) {
            var defaults = {
                position : 0,
                color : Colors.getColor('grey')
            };
            return $.extend({},defaults,customs);
        }
    }])

    .factory('newGradient',['Colors','newMarker', function (Colors, newMarker) {

        function gradient(name) {
            this.angle = -90;
            this.length = null;
            this.distance = null;
            this.markers = [];
            this.name = name || '';
            this.isModeAuto = true;

            //from color
            this.markers.push( newMarker({
                color : Colors.getColor('black'),
                position:0
            }) );

            //to color
            this.markers.push( newMarker({
                color : Colors.getColor('white'),
                position: 100
            }) );
        }

        gradient.prototype.$_sortMarkers = function() {
            var markers = this.markers,
                length = this.markers.length,
                temp;

            for(var i =0; i<length; i++){
                for(var j =0; j<length; j++){
                    if(markers[j+1] && (markers[j].position > markers[j+1].position)){
                        temp = markers[j+1];
                        markers[j+1] = markers[j];
                        markers[j] = temp;
                    }
                }
            }
        }


        return function(gId){
            return new gradient(gId);
        }

    }])

    .directive('gradientPreview',['Colors',function(Colors){
        return {
            restrict: 'A',
            replace: true,
            template :  '<div class="zixys-previewer">'+
                            '<div id="zixys-gradient-preview" style="{{output}}"></div>'+
                        '</div>',
            scope: {
                gradient:"=gradientPreview"
            },
            controller:['$scope','gradList', function($scope, gradList) {

                $scope.gradList = gradList;

                function render(){

                    if(!gradList.selected.markers) {
                       $scope.output = 'background-image:none;';
                       return;
                    }

                    var codeLine = '';
                    for (var i=0; i<gradList.selected.markers.length; i++) {
                        codeLine = codeLine + Colors.stringifyColor(gradList.selected.markers[i].color) +' '+gradList.selected.markers[i].position+'%';
                        if (i != gradList.selected.markers.length-1 ) {
                            codeLine = codeLine + ',';
                        }
                    }

                    $scope.output =
                            'background-image: linear-gradient( left, '+codeLine+');' +
                            'background-image: -o-linear-gradient(left, '+codeLine+');' +
                            'background-image: -moz-linear-gradient(left, '+codeLine+');' +
                            'background-image: -webkit-linear-gradient(left, '+codeLine+');' +
                            'background-image: -ms-linear-gradient(left, '+codeLine+');'
                    gradList.$_deploy();
                }

                $scope.$watch('gradList.selected.markers',render,true);

            }]
        }
    }])

    .directive('markerHandle',[function(){
        return {
            replace : true,
            template :  '<div ng-class="{zixysSelectedMarker : gradList.marker == marker, zixysMarker:true }" style="left:{{marker.position}}%;">' +
                            '<div class="zixys-transparent-handle"></div>'+
                            '<div ng-mousedown="selectMarker()" class="zixys-marker-color" style="background-color:{{stringifyColor(marker.color)}};"></div>'+
                        '</div>',
            scope : {
                marker : '=markerHandle'
            },
            controller : ['$scope','$element','Colors','gradList',function($scope, $element, Colors, gradList){
                $scope.stringifyColor = Colors.stringifyColor;
                $scope.gradList = gradList;

                $scope.selectMarker = function(){
                    gradList.marker = $scope.marker;
                };

                $scope.$watch('gradList.marker.position',function(position){
                    if (typeof position === 'number') {
                        gradList.selected.$_sortMarkers();
                    }
                });
            }]
        }
    }])

    .directive('colorMarkers',['$compile', function ($compile) {
        return {
            restrict: 'A',
            replace: true,
            template:'<div>'+
                        '<div class="zixys-menu-gpreview-wrap">'+
                            '<div gradient-preview="gradient" class="zixys-previewer"></div>'+
                            '<div ng-click="addMarker($event)" id="zixys-gradient-scroller">' +

                                '<div ng-repeat="m in gradList.selected.markers" marker-handle="m"></div>'+

                            '</div>'+
                        '</div>'+
                        '<div class="zixys-menu-block">'+
                            '<div class="zixys-input-box"><span class="zixys-menu-label">color</span><input ng-disabled="!gradList.marker.color" class="color-picker" colorpick="gradList.marker.color"></div>'+
                            '<div class="zixys-input-box"><span class="zixys-menu-label">position(%)</span><input class="zixysSpinner" ng-disabled="gradList.marker.position == undefined" min="0" max="100" ng-model="gradList.marker.position" type="text"></div>'+
                            '<div class="zixys-input-box"><input id="zixys-remove-marker" ng-disabled="!gradList.marker.color" ng-click="removeMarker()" type="button" value="remove" ></div>'+
                        '</div>'+
                     '</div>',
            scope: {},
            controller : ['$scope','gradList','newMarker','$element', function($scope, gradList, newMarker, $element) {
                $scope.gradList = gradList;

                var previewer = $element.find('#zixys-gradient-preview'),
                    pad = $element.find('#zixys-gradient-scroller'),
                    doc = $('body'),
                    scale = pad.innerWidth(), d;


                function calcRelativePosition (cursorX) {
                    d = cursorX - pad.offset().left;

                    if (d > scale) {
                        d = scale;
                    }else if (d < 0) {
                        d = 0;
                    }
                    return parseInt(10*(100*Math.abs(d))/scale)/10;
                }

                function mouseMove(event) {
                    gradList.marker.position = calcRelativePosition(event.pageX);
                    $scope.$digest();
                }

                doc.bind('mousedown.zixysMarker',function(event) {
                    if ( $(event.target).hasClass('zixys-marker-color') ) {
                        //markerNode = findMarkerNodeByNode(event.target);
                        //selectMarkerNode(markerNode);

                        doc.bind('mousemove.zixysMarker',mouseMove);
                        // cancel out any text selections
                        document.body.focus();
                        // prevent text selection in IE
                        document.onselectstart = function () {
                            return false;
                        };
                        return false;
                    }
                }).bind('mouseup.zixysSlider', function(event) {
                        // we're done with these events until the next OnMouseDown
                        document.onmousemove = undefined;
                        document.onselectstart = undefined;
                        doc.unbind('mousemove.zixysMarker');
                });

                $scope.addMarker = function(event){
                    if (event.target !== pad[0]) return;

                    if(gradList.selected.markers) {
                        gradList.selected.markers.push(newMarker({
                            position : calcRelativePosition(event.pageX)
                        }));
                        gradList.selected.$_sortMarkers();
                    }
                }

                $scope.removeMarker = function() {
                    if(gradList.selected && gradList.selected.markers.length>2) {
                        for(i=0; i< gradList.selected.markers.length; i++){
                            if(gradList.marker === gradList.selected.markers[i]){
                                gradList.selected.markers.splice(i,1);
                                gradList.marker = {};
                                break;
                            }
                        }
                    }
                }

            }]
        }
    }])

    .service('gradientPresets',[function(){

	    this.textDefaults = [
            '#cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%',
            '#4c4c4c 0%, #595959 12%, #666666 25%, #474747 39%, #2c2c2c 50%, #000000 51%, #111111 60%, #2b2b2b 76%, #1c1c1c 91%, #131313 100%',
            '#87e0fd 0%, #53cbf1 40%, #05abe0 100%',
            '#f0f9ff 0%, #cbebff 47%, #a1dbff 100%',
            '#7abcff 0%, #60abf8 44%, #4096ee 100%',
            '#00b7ea 0%, #009ec3 100%',
            '#88bfe8 0%, #70b0e0 100%',
            '#feffff 0%, #ddf1f9 35%, #a0d8ef 100%',
            '#b8e1fc 0%, #a9d2f3 10%, #90bae4 25%, #90bcea 37%, #90bff0 50%, #6ba8e5 51%, #a2daf5 83%, #bdf3fd 100%',
            '#3b679e 0%, #2b88d9 50%, #207cca 51%, #7db9e8 100%',
            '#6db3f2 0%, #54a3ee 50%, #3690f0 51%, #1e69de 100%',
            '#ebf1f6 0%, #abd3ee 50%, #89c3eb 51%, #d5ebfb 100%',
            '#e4f5fc 0%, #bfe8f9 50%, #9fd8ef 51%, #2ab0ed 100%',
            '#cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%',
            '#a7c7dc 0%, #85b2d3 100%',
            '#3f4c6b 0%, #3f4c6b 100%',
            '#d0e4f7 0%, #73b1e7 24%, #0a77d5 50%, #539fe1 79%, #87bcea 100%',
            '#e1ffff 0%, #e6f8fd 30%, #c8eefb 54%, #bee4f8 75%, #b1d8f5 100%',
            '#b3dced 0%, #29b8e5 50%, #bce0ee 100%',
            '#d5cea6 0%, #c9c190 40%, #b7ad70 100%',
            '#f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%',
            '#a90329 0%, #8f0222 44%, #6d0019 100%',
            '#fefcea 0%, #f1da36 100%',
            '#b4ddb4 0%, #83c783 17%, #52b152 33%, #008a00 67%, #005700 83%, #002400 100%',
            '#cdeb8e 0%, #a5c956 100%',
            '#c9de96 0%, #8ab66b 44%, #398235 100%',
            '#f8ffe8 0%, #e3f5ab 33%, #b7df2d 100%',
            '#a9db80 0%, #96c56f 100%',
            '#b4e391 0%, #61c419 50%, #b4e391 100%',
            '#9dd53a 0%, #a1d54f 50%, #80c217 51%, #7cbc0a 100%',
            '#e6f0a3 0%, #d2e638 50%, #c3d825 51%, #dbf043 100%',
            '#bfd255 0%, #8eb92a 50%, #72aa00 51%, #9ecb2d 100%',
            '#eeeeee 0%, #cccccc 100%',
            '#cedce7 0%, #596a72 100%',
            '#606c88 0%, #3f4c6b 100%',
            '#b0d4e3 0%, #88bacf 100%',
            '#f2f5f6 0%, #e3eaed 37%, #c8d7dc 100%',
            '#d8e0de 0%, #aebfbc 22%, #99afab 33%, #8ea6a2 50%, #829d98 67%, #4e5c5a 82%, #0e0e0e 100%',
            '#b5bdc8 0%, #828c95 36%, #28343b 100%',
            '#b8c6df 0%, #6d88b7 100%',
            '#cfe7fa 0%, #6393c1 100%',
            '#d2dfed 0%, #c8d7eb 26%, #bed0ea 51%, #a6c0e3 51%, #afc7e8 62%, #bad0ef 75%, #99b5db 88%, #799bc8 100%',
            '#e2e2e2 0%, #dbdbdb 50%, #d1d1d1 51%, #fefefe 100%',
            '#f2f6f8 0%, #d8e1e7 50%, #b5c6d0 51%, #e0eff9 100%',
            '#d4e4ef 0%, #86aecc 100%',
            '#f5f6f6 0%, #dbdce2 21%, #b8bac6 49%, #dddfe3 80%, #f5f6f6 100%',
            '#f3e2c7 0%, #c19e67 50%, #b68d4c 51%, #e9d4b3 100%',
            '#f9fcf7 0%, #f5f9f0 100%',
            '#c3d9ff 0%, #b1c8ef 41%, #98b0d9 100%',
            '#d2ff52 0%, #91e842 100%',
            '#fefefd 0%, #dce3c4 42%, #aebf76 100%',
            '#e4efc0 0%, #abbd73 100%',
            '#a4b357 0%, #75890c 100%',
            '#627d4d 0%, #1f3b08 100%',
            '#ffaf4b 0%, #ff920a 100%',
            '#fac695 0%, #f5ab66 47%, #ef8d31 100%',
            '#ffc578 0%, #fb9d23 100%',
            '#fceabb 0%, #fccd4d 50%, #f8b500 51%, #fbdf93 100%',
            '#ffa84c 0%, #ff7b0d 100%',
            '#ffb76b 0%, #ffa73d 50%, #ff7c00 51%, #ff7f04 100%',
            '#ff5db1 0%, #ef017c 100%',
            '#fb83fa 0%, #e93cec 100%',
            '#e570e7 0%, #c85ec7 47%, #a849a3 100%',
            '#cb60b3 0%, #ad1283 50%, #de47ac 100%',
            '#fcecfc 0%, #fba6e1 50%, #fd89d7 51%, #ff7cd8 100%',
            '#cb60b3 0%, #c146a1 50%, #a80077 51%, #db36a4 100%',
            '#ebe9f9 0%, #d8d0ef 50%, #cec7ec 51%, #c1bfea 100%',
            '#febbbb 0%, #fe9090 45%, #ff5c5c 100%',
            '#f2825b 0%, #e55b2b 50%, #f07146 100%',
            '#ff3019 0%, #cf0404 100%',
            '#f85032 0%, #f16f5c 50%, #f6290c 51%, #f02f17 71%, #e73827 100%',
            '#feccb1 0%, #f17432 50%, #ea5507 51%, #fb955e 100%',
            '#efc5ca 0%, #d24b5a 50%, #ba2737 51%, #f18e99 100%',
            '#f3c5bd 0%, #e86c57 50%, #ea2803 51%, #ff6600 75%, #c72200 100%',
            '#b7deed 0%, #71ceef 50%, #21b4e2 51%, #b7deed 100%',
            '#e0f3fa 0%, #d8f0fc 50%, #b8e2f6 51%, #b6dffd 100%',
            '#feffe8 0%, #d6dbbf 100%',
            '#fcfff4 0%, #e9e9ce 100%',
            '#fcfff4 0%, #dfe5d7 40%, #b3bead 100%',
            '#e5e696 0%, #d1d360 100%',
            '#7d7e7d 0%, #0e0e0e 100%',
            '#959595 0%, #0d0d0d 46%, #010101 50%, #0a0a0a 53%, #4e4e4e 76%, #383838 87%, #1b1b1b 100%',
            '#aebcbf 0%, #6e7774 50%, #0a0e0a 51%, #0a0809 100%',
            '#c5deea 0%, #8abbd7 31%, #066dab 100%',
            '#f7fbfc 0%, #d9edf2 40%, #add9e4 100%',
            '#d6f9ff 0%, #9ee8fa 100%',
            '#e9f6fd 0%, #d3eefb 100%',
            '#63b6db 0%, #309dcf 100%',
            '#a9e4f7 0%, #0fb4e7 100%',
            '#93cede 0%, #75bdd1 41%, #49a5bf 100%',
            '#b2e1ff 0%, #66b6fc 100%',
            '#deefff 0%, #98bede 100%',
            '#feffff 0%, #d2ebf9 100%',
            '#a7cfdf 0%, #23538a 100%',
            '#ffffff 0%, #f1f1f1 50%, #e1e1e1 51%, #f6f6f6 100%',
            '#f6f8f9 0%, #e5ebee 50%, #d7dee3 51%, #f5f7f9 100%',
            '#F2F6F8 0%, #D8E1E7 50%, #B5C6D0 51%, #E0EFF9 100%',
            '#f6e6b4 0%, #ed9017 100%',
            '#eab92d 0%, #c79810 100%',
            '#ffd65e 0%, #febf04 100%',
            '#f1e767 0%, #feb645 100%'
        ];

        this.deployed = {};

    }])
    
    .service('gTools',[function () {
        var context,$canvas, pageWidth, pageHeight, elementWidth, elementHeight, gradientStarted, self = this;
        var $body = $('body'), $preview = $('#zixys-gradient-tab #zixys-gradient-preview');
        this.gradientStarted = false;
        this.$body = $body;
        this.$preview = $preview;
        this.node;
        
        function createCanvas (){
            $body.append('<div id="gCanvasWrap" style="position:absolute; top:0; left:0; width:'+pageWidth+'px; height:'+pageHeight+'px;"><canvas id="gCanvas" width="'+pageWidth+'px" height="'+pageHeight+'px"></canvas></div>');
            $canvas = $body.children('#gCanvasWrap').children('#gCanvas');
            context = $canvas[0].getContext("2d");
            context.clearRect(0,0,pageWidth,pageHeight);
        };

        function destroyCanvas () {
            $canvas.remove();
            $body.children('#gCanvasWrap').remove();
        };	
        
        function line (x0,y0,x1,y1) {
            context.beginPath();
            context.moveTo(x0,y0);
            context.lineTo(x1,y1);
            context.stroke();
        };

        function refreshSelectors (){
            pageWidth = $body.outerWidth();
            pageHeight = $body.outerHeight();
            elementWidth = self.node.outerWidth();
            elementHeight = self.node.outerHeight();
        };

        this.startLine = function (x,y) {
            createCanvas();
            $body.bind('mousemove.zixys',function(event){
                context.clearRect(0,0,pageWidth,pageHeight);
                line(x,y,event.pageX,event.pageY);			
            });
        };

        this.endLine = function() {
            $body.unbind('mousemove.zixys');
            destroyCanvas();
        };
        
        this.getGradientLineData = function(p0,p1){
            var a,b,c,angle,kp,kr,kg,mg,r;
            var quadrant;
            /****************** math part *****************/
            function calcQuadrant1(){
                angle = - Math.asin(b/c) *(180/3.14) + 360;

                //--- calc Xr, Yr ---
                Xr = kp/(mg + 1/mg);
                Yr = mg*Xr;
                //-----------------------
                //
                //--- calculate
                r = Math.sqrt(Xr*Xr + Yr*Yr);
            //------------------
            };
		
            function calcQuadrant2 (){
                angle = Math.asin(b/c)*(180/3.14)+180 ;
			
                //--- calc kr -----
                kr = - mg*elementWidth;
                //------------------
			
                //--- calc Xr, Yr ---
                Xr = (kp-kr)/(mg + 1/mg);
                Yr = mg*Xr + kr;
                //-----------------------
			
                //--- calculate R!!! ---
                r = Math.sqrt((elementWidth - Xr)*(elementWidth - Xr) + Yr*Yr);
            //------------------------
            };

            function calcQuadrant3 (){
                angle = Math.asin(b/c) *(180/3.14)+180;
			
                //--- calc kr -----
                kr = elementHeight - mg*elementWidth;
                //------------------
			
                //--- calc Xr, Yr ---
                Xr = (kp-kr)/(mg + 1/mg);
                Yr = mg*Xr + kr;
                //-----------------------
			
                //--- calculate R!!! ---
                r = Math.sqrt((elementWidth - Xr)*(elementWidth - Xr) + (elementHeight-Yr)*(elementHeight-Yr));
            //------------------------
			
            };

            function calcQuadrant4 (){
                angle = - Math.asin(b/c) *(180/3.14);
			
                //--- calc kr -----
                kr = elementHeight;
                //------------------
			
                //--- calc Xr, Yr ---
                Xr = (kp-kr)/(mg + 1/mg);
                Yr = mg*Xr + kr;
                //-----------------------
			
                //--- calculate R!!! ---
                r = Math.sqrt( Xr*Xr + (elementHeight-Yr)*(elementHeight-Yr));
            //------------------------
            };

            var _b = p1.y - p0.y;
            var _a = p1.x - p0.x;

			
            b = p1.y - p0.y;
            a = p1.x - p0.x;
            c = Math.sqrt( a*a + b*b );
			
            //----- calc Yg ----
            mg = b/a;
            kg = -p0.x * (b/a) + p0.y;
            //----------------
			
            //---- calc Yp ----
            kp = p0.y + (1/mg)*p0.x;
            //-------------------
			
            //-----  find quadrant -------
            if(_a>0 && _b>0){
                //1st
                calcQuadrant1();
                quadrant = 1;
            }else
            if(_a<0 && _b>0){
                //2nd
                calcQuadrant2();
                quadrant = 2;
            //quadrant = 90;
            }else
            if(_a<0 && _b<0){
                //3rd
                calcQuadrant3();
                quadrant = 3;
            //quadrant = 180;
            }else
            if(_a>0 && _b<0){
                //4th
                calcQuadrant4();
                quadrant = 4;
            //quadrant = 270;
            }else{

                if(_a==0 && b==0){
                    return;
                };
				
                if(_a==0){
                    if(b>0){
                        r=p0.y;
                        angle=270;
                    }else{
                        r = elementHeight - p0.y;
                        angle=90;
                    }
                }else
                if(b==0 ){
                    if(a>0){
                        r=p0.x;
                        angle=0;
                    }else{
                        r = elementWidth - p0.x;
                        angle=180;
                    }
                }
            }
            return {
                distance:r,
                length:c,
                angle:angle,
                quadrant:quadrant
            }
        };
        /*******************************************/
        
        this.getClickCoordinates = function(event, node){
            if(!node){
                return;
            }
			
            refreshSelectors();
            
            return {
                page : {
                    x : event.pageX,
                    y : event.pageY
                },
                element : {
                    x : event.pageX - node.offset().left,
                    y : event.pageY - node.offset().top                    
                }
            };

        };

    }])

    .directive('gradientTab',function(){
        return {
            restrict: 'C',
            replace: false,
            template:
                '<div id="zixys-gradient-tab" ng-controller="gradientCtrl">'+
                        '<div class="zixys-menu-block">'+
                        '<div class="zixys-input-box">'+
                                '<em class="drawButton" zixys-button="drawButton" ></em>'+
                                '<label for="zixys-mode-manual" class="zixys-radio-label-first">manual</label>'+
                                '<input id="zixys-mode-manual" ng-model="gradList.selected.isModeAuto" ng-value="false" ng-disabled="!gradList.selected.name" type="radio" >'+
                                '<label for="zixys-mode-auto" class="zixys-radio-label">auto</label>'+
                                '<input id="zixys-mode-auto" ng-model="gradList.selected.isModeAuto" ng-value="true" ng-disabled="!gradList.selected.name" type="radio" >'+
                        '</div>'+
                        '<div class="zixys-gr-select-list">' +
                            '<div select-list="gradList.selected" source="gradList.list" item="name" options="gardListOpts"></div>' +
                            '<div class="zixys-sl-controls">' +
                                '<input type="button" ng-click="addGradient()" value="+"  ng-disabled="noElement" >' +
                                '<input type="button" ng-click="removeGradient()" value="-"  ng-disabled="noElement">' +
                            '</div>'+
                        '</div>'+
                        '</div>'+
                        '<div class="zixys-menu-block">'+
                                '<div class="zixys-input-box"><span class="zixys-menu-label">distance</span><input ng-model="gradList.selected.distance" ng-disabled="gradList.selected.isModeAuto || !gradList.selected.name" class="zixys-spinner" min="0" type="text"></div>'+
                                '<div class="zixys-input-box"><span class="zixys-menu-label">length</span><input ng-model="gradList.selected.length" ng-disabled="gradList.selected.isModeAuto || !gradList.selected.name " class="zixys-spinner" min="0" type="text"></div>'+
                                '<div class="zixys-input-box"><span class="zixys-menu-label">angle(deg)</span><input ng-model="gradList.selected.angle"  ng-disabled="gradList.list.length==0" class="zixys-spinner" type="text"></div>'+
                        '</div>'+
                        '<div ng-disabled="noGradient" color-markers="gradient"></div>'+
                        '<div class="zixys-template-action">' +
                            '<div ng-disabled="noElement" class="zixys-presets"></div>'+
//                            '<input type="button" ng-click="addGradient()" value="Add Gradient"  ng-disabled="noElement" />'+
//                            '<input type="button" ng-click="removeGradient()" value="Remove"  ng-disabled="noElement" />'+
                        '</div>'+
                '</div>',


            link: function($scope, element, attrs) {
                
            }
        }
    })
    
    .controller('gradientCtrl',['$scope','gTools','gradientPresets','Colors','gradList', 'newGradient','zxNodes',function($scope, gTools, gradientPresets, Colors, gradList, newGradient, zxNodes ) {
       
        var p0,p1, zxNode, inc=0;

        $scope.gradList = gradList;
        $scope.noElement = true;

        $scope.drawButton = {
            iconClass:'zixys-gradient',
            initStateDisabled:true
        }

        $scope.gardListOpts = {
            remove:false
        }

        $scope.zxNodes = zxNodes;

        gTools.$body.bind('click.zixys',function(event){
            
            if(!gTools.node || !$scope.drawButton.isPressed() ) return;
            
            var gradientData;
            if(!gTools.gradientStarted){
                p0 = gTools.getClickCoordinates(event, gTools.node);
                gTools.startLine(p0.page.x,p0.page.y);
                gTools.gradientStarted = true;
            }else{
                p1 = gTools.getClickCoordinates(event, gTools.node);
                gTools.endLine();
                gradientData = gTools.getGradientLineData(p0.element,p1.element);
                if(gradientData) {
                    gradList.selected.length = parseInt(gradientData.length);
                    gradList.selected.distance = parseInt(gradientData.distance);
                    gradList.selected.angle = parseInt(gradientData.angle);
                    $scope.$digest();
                    $scope.drawButton.release();
                };

                gTools.gradientStarted = false;
            }
        });
        
        function draw(newVal,oldVal) {
            if(newVal === oldVal) return;
            gradList.$_deploy();
        }

        $scope.addGradient = function () {
            gradList.selected = newGradient('gr-'+(inc++));
            gradList.list.unshift(gradList.selected);
        }

        $scope.removeGradient = function(){
            for(var i = 0; i<gradList.list.length; i++){
                if (gradList.list[i] === gradList.selected) {
                    gradList.list.splice(i,1);
                    gradList.selected = gradList.list[i-1] || {};
                    break;
                }
            }
        }

        $scope.$watch('zxNodes.selected',function(zixysNode){

            if(zixysNode) {
                $scope.noElement = false;
                zxNode = zixysNode;
                if(zxNode.hasOneNode) {
                    gTools.node = zxNode.nodes;
                } else {
                    gTools.node = null;
                }

                gradList.zxNode = zixysNode;
                if (zxNode.data && zxNode.data.gradient) {
                    gradList.list = zxNode.data.gradient;
                    gradList.selected = gradList.list[0]||{};
                    gradList.marker = {};
                } else {
                    gradList.$_reset();
                }
            } else {
                $scope.noElement = true;
                gradList.zxNode = null;
            }
        })

        $scope.$watch('gradList.selected.length',draw);
        $scope.$watch('gradList.selected.distance',draw);
        $scope.$watch('gradList.selected.angle',draw);

        $scope.$watch('gradList.selected.isModeAuto',function (isAuto,oldVal) {
            if(isAuto === oldVal) return;
            isAuto === false ? $scope.drawButton.enable() : $scope.drawButton.disable();
            draw(isAuto);
        });

        $scope.$watch('gradList.selected',function(){
            if(gradList.selected.name){
                gradList.marker = {};
            }
        });

    }])

    .run(['$rootScope', 'registerCompiler', 'Colors', function ($rootScope, registerCompiler, Colors) {

        registerCompiler({
            name:'gradient',
            property : 'background-image',
            export: "variant",
            compile : function(data) {
                var codeLine = '',
                    statements = ['linear-gradient','-o-linear-gradient','-moz-linear-gradient','-webkit-linear-gradient','-ms-linear-gradient'],
                    values = [], output = [], tmpGradent, tmpMarkers;

                for (var i = 0; i<data.length; i++) {
                    tmpGradent = data[i];
                    tmpMarkers = data[i].markers;
                    codeLine = codeLine + tmpGradent.angle + 'deg, ';
                    if(tmpGradent.isModeAuto) {
                        for (var j=0; j<tmpMarkers.length; j++) {
                            codeLine = codeLine + Colors.stringifyColor(tmpMarkers[j].color)+ ' '+tmpMarkers[j].position+'%' + (j<tmpMarkers.length-1? ',':'');
                        }
                    } else {
                        for (var j=0; j<tmpMarkers.length; j++) {
                            codeLine = codeLine + Colors.stringifyColor(tmpMarkers[j].color)+ ' '+(tmpGradent.distance + (tmpMarkers[j].position * tmpGradent.length)/100 )+'px' + (j<tmpMarkers.length-1? ',':'');
                        }
                    }
                    values.push(codeLine);
                    codeLine = '';
                }
                codeLine = '';
                for (var i = 0; i<statements.length; i++) {
                    for (var j = 0; j<values.length; j++) {
                        codeLine =codeLine + statements[i] + '('+values[j]+')'+( (j==values.length-1) ? '' : ',' );
                    }
                    output.push(codeLine);
                    codeLine = '';
                }
                return output;
            }
        });

        $rootScope.$on('zixysDomReady',function(event,params) {
            $rootScope.addTab('Gradient','gradient-tab');
        });
        
    }]);
    
    